﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Threading;
using CYTS.Aoyou.Framework.Utility;

namespace CYTS.Aoyou.Framework.Database
{
    public class SqlMapFactory
    {
        private static Dictionary<string, SqlMap> SqlMapHash = new Dictionary<string, SqlMap>();
        private static readonly object StartLock = new object();

        static SqlMapFactory()
        {
            FileMonitorHelper.OnFileModified += FileMonitorHelper_OnFileModified;
        }

        static void FileMonitorHelper_OnFileModified(FileInfo file)
        {
            if (file.Extension.ToLower() == ".sqlmap")
            {
                UpdateOneSqlmap(file.Name.ToLower().Replace(".sqlmap", ""));
            }
        }

        public static SqlMap GetSqlmap(string sqlmapName)
        {
            try
            {
                if (!SqlMapHash.ContainsKey(sqlmapName))
                {
                    GetSqlmapFromFile(sqlmapName);
                }
                return SqlMapHash[sqlmapName];
            }
            catch (Exception ex)
            {
                string msg = string.Format("获取sqlmap出现异常，sqlmapName={0}", sqlmapName);
                throw new Exception(msg, ex);
            }
        }

        private static void GetSqlmapFromFile(string sqlmapName)
        {
            try
            {
                Monitor.Enter(StartLock);
                #region 将配置实例加入配置列表

                //如果有其他线程将配置加载到内存了，那么不需要再次加载配置
                if (SqlMapHash.ContainsKey(sqlmapName))
                {
                    return;
                }

                #endregion

                //从本地配置文件加载配置到内存

                //=====开始加载配置（本地文件）=====

                UpdateOneSqlmap(sqlmapName);

                //=====完成加载配置（本地文件）=====

            }
            catch (Exception ex)
            {
                string msg = string.Format("获取sqlmap出现异常 将无法获取对应的数据，sqlmapName={0}", sqlmapName); 
                throw new Exception(msg, ex);
            }
            finally
            {
                Monitor.Exit(StartLock);
            }
        }

        private static bool UpdateOneSqlmap(string sqlmapName)
        {
            bool retVal = true;
            try
            {
                var temp = OnUpdate(sqlmapName);

                //更新_ConfigUnitHash，将配置实例的透明代理放到hash中
                SqlMapHash[sqlmapName] = temp;
            }
            catch (Exception ex)
            {
                retVal = false;
                string msg = "UpdateOneConfig失败";
                throw new Exception(msg, ex);
            }
            return retVal;
        }

        private static SqlMap OnUpdate(string sqlmapName)
        {
            try
            {
                string fileName = sqlmapName.ToLower() + ".sqlmap";
                if (!FileMonitorHelper.MonitorFileFullPathDic.ContainsKey(fileName))
                {
                    string msg = string.Format("'{0}'下（包括子文件夹）不存在'{1}'", FileMonitorHelper.Path, fileName);
                    throw new Exception(msg);
                }

                string filePath = FileMonitorHelper.MonitorFileFullPathDic[fileName];
                SqlMap conf = SerializationHelper.Load(typeof(SqlMap), filePath) as SqlMap;
                return conf;
            }
            catch (Exception ex)
            {
                string msg = sqlmapName.ToLower() + ".sqlmap 文件序列化错误";
                throw new Exception(msg, ex);
            }
        }
    }
}
